/**
 * 音效管理器
 * 管理应用中的音效播放、音频反馈和音量控制
 */

/**
 * 音效类型枚举
 */
export const AUDIO_TYPES = {
	// 界面音效
	CLICK: 'click',
	SUCCESS: 'success',
	ERROR: 'error',
	WARNING: 'warning',
	NOTIFICATION: 'notification',
	
	// 游戏音效
	GAME_START: 'gameStart',
	GAME_END: 'gameEnd',
	LEVEL_UP: 'levelUp',
	CORRECT: 'correct',
	INCORRECT: 'incorrect',
	TIME_WARNING: 'timeWarning',
	COUNTDOWN: 'countdown',
	
	// 成就音效
	ACHIEVEMENT: 'achievement',
	PERSONAL_BEST: 'personalBest',
	STREAK: 'streak',
	
	// 背景音乐
	BACKGROUND: 'background',
	AMBIENT: 'ambient'
}

/**
 * 音效配置
 */
const AUDIO_CONFIG = {
	[AUDIO_TYPES.CLICK]: {
		url: '/static/audio/click.mp3',
		volume: 0.3,
		duration: 100,
		loop: false,
		preload: true
	},
	[AUDIO_TYPES.SUCCESS]: {
		url: '/static/audio/success.mp3',
		volume: 0.5,
		duration: 800,
		loop: false,
		preload: true
	},
	[AUDIO_TYPES.ERROR]: {
		url: '/static/audio/error.mp3',
		volume: 0.4,
		duration: 600,
		loop: false,
		preload: true
	},
	[AUDIO_TYPES.WARNING]: {
		url: '/static/audio/warning.mp3',
		volume: 0.4,
		duration: 500,
		loop: false,
		preload: true
	},
	[AUDIO_TYPES.NOTIFICATION]: {
		url: '/static/audio/notification.mp3',
		volume: 0.6,
		duration: 1000,
		loop: false,
		preload: true
	},
	[AUDIO_TYPES.GAME_START]: {
		url: '/static/audio/game-start.mp3',
		volume: 0.7,
		duration: 1500,
		loop: false,
		preload: true
	},
	[AUDIO_TYPES.GAME_END]: {
		url: '/static/audio/game-end.mp3',
		volume: 0.6,
		duration: 2000,
		loop: false,
		preload: true
	},
	[AUDIO_TYPES.LEVEL_UP]: {
		url: '/static/audio/level-up.mp3',
		volume: 0.6,
		duration: 1200,
		loop: false,
		preload: true
	},
	[AUDIO_TYPES.CORRECT]: {
		url: '/static/audio/correct.mp3',
		volume: 0.4,
		duration: 400,
		loop: false,
		preload: true
	},
	[AUDIO_TYPES.INCORRECT]: {
		url: '/static/audio/incorrect.mp3',
		volume: 0.4,
		duration: 600,
		loop: false,
		preload: true
	},
	[AUDIO_TYPES.TIME_WARNING]: {
		url: '/static/audio/time-warning.mp3',
		volume: 0.5,
		duration: 800,
		loop: true,
		preload: true
	},
	[AUDIO_TYPES.COUNTDOWN]: {
		url: '/static/audio/countdown.mp3',
		volume: 0.5,
		duration: 1000,
		loop: false,
		preload: true
	},
	[AUDIO_TYPES.ACHIEVEMENT]: {
		url: '/static/audio/achievement.mp3',
		volume: 0.7,
		duration: 2000,
		loop: false,
		preload: true
	},
	[AUDIO_TYPES.PERSONAL_BEST]: {
		url: '/static/audio/personal-best.mp3',
		volume: 0.8,
		duration: 2500,
		loop: false,
		preload: true
	},
	[AUDIO_TYPES.STREAK]: {
		url: '/static/audio/streak.mp3',
		volume: 0.6,
		duration: 1500,
		loop: false,
		preload: true
	},
	[AUDIO_TYPES.BACKGROUND]: {
		url: '/static/audio/background.mp3',
		volume: 0.2,
		duration: 0, // 循环播放
		loop: true,
		preload: false
	},
	[AUDIO_TYPES.AMBIENT]: {
		url: '/static/audio/ambient.mp3',
		volume: 0.15,
		duration: 0, // 循环播放
		loop: true,
		preload: false
	}
}

/**
 * 音频管理器类
 */
class AudioManager {
	constructor() {
		this.audioContext = null
		this.audioInstances = new Map()
		this.preloadedAudio = new Map()
		this.isEnabled = true
		this.masterVolume = 1.0
		this.categoryVolumes = {
			ui: 1.0,
			game: 1.0,
			achievement: 1.0,
			background: 1.0
		}
		this.currentBackgroundAudio = null
		this.fadeTimers = new Map()
		
		this.init()
	}
	
	/**
	 * 初始化音频管理器
	 */
	init() {
		this.loadSettings()
		this.setupAudioContext()
		this.preloadAudio()
		this.setupEventListeners()
	}
	
	/**
	 * 加载音频设置
	 */
	loadSettings() {
		try {
			if (typeof uni !== 'undefined') {
				const settings = uni.getStorageSync('audioSettings')
				if (settings) {
					this.isEnabled = settings.isEnabled !== false
					this.masterVolume = settings.masterVolume || 1.0
					this.categoryVolumes = { ...this.categoryVolumes, ...settings.categoryVolumes }
				}
			}
		} catch (error) {
			console.error('加载音频设置失败:', error)
		}
	}
	
	/**
	 * 设置音频上下文
	 */
	setupAudioContext() {
		try {
			if (typeof window !== 'undefined' && (window.AudioContext || window.webkitAudioContext)) {
				this.audioContext = new (window.AudioContext || window.webkitAudioContext)()
			}
		} catch (error) {
			console.warn('音频上下文初始化失败:', error)
		}
	}
	
	/**
	 * 预加载音频文件
	 */
	preloadAudio() {
		Object.entries(AUDIO_CONFIG).forEach(([type, config]) => {
			if (config.preload) {
				this.loadAudioFile(type, config)
			}
		})
	}
	
	/**
	 * 加载音频文件
	 * @param {string} type - 音频类型
	 * @param {Object} config - 音频配置
	 */
	loadAudioFile(type, config) {
		try {
			if (typeof uni !== 'undefined') {
				// uni-app环境
				const audio = uni.createInnerAudioContext()
				audio.src = config.url
				audio.volume = config.volume * this.getCategoryVolume(type) * this.masterVolume
				audio.loop = config.loop
				
				audio.onError((error) => {
					console.error(`音频加载失败 ${type}:`, error)
				})
				
				this.preloadedAudio.set(type, audio)
			} else if (typeof Audio !== 'undefined') {
				// 浏览器环境
				const audio = new Audio(config.url)
				audio.volume = config.volume * this.getCategoryVolume(type) * this.masterVolume
				audio.loop = config.loop
				audio.preload = 'auto'
				
				audio.onerror = (error) => {
					console.error(`音频加载失败 ${type}:`, error)
				}
				
				this.preloadedAudio.set(type, audio)
			}
		} catch (error) {
			console.error(`创建音频实例失败 ${type}:`, error)
		}
	}
	
	/**
	 * 设置事件监听器
	 */
	setupEventListeners() {
		// 监听应用进入后台/前台
		if (typeof uni !== 'undefined') {
			uni.onAppHide(() => {
				this.pauseBackgroundAudio()
			})
			
			uni.onAppShow(() => {
				this.resumeBackgroundAudio()
			})
		}
		
		// 监听页面可见性变化
		if (typeof document !== 'undefined') {
			document.addEventListener('visibilitychange', () => {
				if (document.hidden) {
					this.pauseBackgroundAudio()
				} else {
					this.resumeBackgroundAudio()
				}
			})
		}
	}
	
	/**
	 * 播放音效
	 * @param {string} type - 音效类型
	 * @param {Object} options - 播放选项
	 * @returns {Promise} 播放Promise
	 */
	play(type, options = {}) {
		return new Promise((resolve, reject) => {
			if (!this.isEnabled) {
				resolve()
				return
			}
			
			const config = AUDIO_CONFIG[type]
			if (!config) {
				console.warn(`未知音效类型: ${type}`)
				reject(new Error(`未知音效类型: ${type}`))
				return
			}
			
			try {
				let audio = this.preloadedAudio.get(type)
				
				if (!audio) {
					this.loadAudioFile(type, config)
					audio = this.preloadedAudio.get(type)
				}
				
				if (!audio) {
					reject(new Error(`音频实例创建失败: ${type}`))
					return
				}
				
				// 应用选项
				if (options.volume !== undefined) {
					audio.volume = options.volume * this.getCategoryVolume(type) * this.masterVolume
				}
				
				if (options.loop !== undefined) {
					audio.loop = options.loop
				}
				
				// 播放音频
				if (typeof uni !== 'undefined' && audio.play) {
					// uni-app环境
					audio.play()
					audio.onPlay(() => resolve())
					audio.onError((error) => reject(error))
				} else if (audio.play) {
					// 浏览器环境
					const playPromise = audio.play()
					if (playPromise) {
						playPromise.then(resolve).catch(reject)
					} else {
						resolve()
					}
				}
				
				// 记录播放实例
				const instanceId = this.generateInstanceId()
				this.audioInstances.set(instanceId, {
					type,
					audio,
					startTime: Date.now(),
					options
				})
				
				// 自动清理
				if (config.duration > 0) {
					setTimeout(() => {
						this.audioInstances.delete(instanceId)
					}, config.duration)
				}
				
			} catch (error) {
				console.error(`播放音效失败 ${type}:`, error)
				reject(error)
			}
		})
	}
	
	/**
	 * 停止音效
	 * @param {string} type - 音效类型
	 */
	stop(type) {
		const audio = this.preloadedAudio.get(type)
		if (audio) {
			try {
				if (typeof uni !== 'undefined' && audio.stop) {
					audio.stop()
				} else if (audio.pause) {
					audio.pause()
					audio.currentTime = 0
				}
			} catch (error) {
				console.error(`停止音效失败 ${type}:`, error)
			}
		}
		
		// 清理实例记录
		for (const [instanceId, instance] of this.audioInstances.entries()) {
			if (instance.type === type) {
				this.audioInstances.delete(instanceId)
			}
		}
	}
	
	/**
	 * 播放背景音乐
	 * @param {string} type - 背景音乐类型
	 * @param {Object} options - 播放选项
	 */
	playBackground(type = AUDIO_TYPES.BACKGROUND, options = {}) {
		// 停止当前背景音乐
		if (this.currentBackgroundAudio) {
			this.stopBackground()
		}
		
		this.currentBackgroundAudio = type
		this.play(type, { loop: true, ...options })
			.then(() => {
				console.log(`开始播放背景音乐: ${type}`)
			})
			.catch(error => {
				console.error(`播放背景音乐失败: ${type}`, error)
			})
	}
	
	/**
	 * 停止背景音乐
	 */
	stopBackground() {
		if (this.currentBackgroundAudio) {
			this.stop(this.currentBackgroundAudio)
			this.currentBackgroundAudio = null
		}
	}
	
	/**
	 * 暂停背景音乐
	 */
	pauseBackgroundAudio() {
		if (this.currentBackgroundAudio) {
			const audio = this.preloadedAudio.get(this.currentBackgroundAudio)
			if (audio && audio.pause) {
				audio.pause()
			}
		}
	}
	
	/**
	 * 恢复背景音乐
	 */
	resumeBackgroundAudio() {
		if (this.currentBackgroundAudio && this.isEnabled) {
			const audio = this.preloadedAudio.get(this.currentBackgroundAudio)
			if (audio && audio.play) {
				try {
					audio.play()
				} catch (error) {
					console.error('恢复背景音乐失败:', error)
				}
			}
		}
	}
	
	/**
	 * 淡入音效
	 * @param {string} type - 音效类型
	 * @param {number} duration - 淡入时长（毫秒）
	 * @param {Object} options - 播放选项
	 */
	fadeIn(type, duration = 1000, options = {}) {
		const targetVolume = options.volume || AUDIO_CONFIG[type]?.volume || 0.5
		
		this.play(type, { ...options, volume: 0 })
			.then(() => {
				const audio = this.preloadedAudio.get(type)
				if (audio) {
					this.animateVolume(audio, 0, targetVolume, duration)
				}
			})
			.catch(error => {
				console.error(`淡入音效失败 ${type}:`, error)
			})
	}
	
	/**
	 * 淡出音效
	 * @param {string} type - 音效类型
	 * @param {number} duration - 淡出时长（毫秒）
	 */
	fadeOut(type, duration = 1000) {
		const audio = this.preloadedAudio.get(type)
		if (audio) {
			const currentVolume = audio.volume
			this.animateVolume(audio, currentVolume, 0, duration, () => {
				this.stop(type)
			})
		}
	}
	
	/**
	 * 音量动画
	 * @param {Object} audio - 音频对象
	 * @param {number} fromVolume - 起始音量
	 * @param {number} toVolume - 目标音量
	 * @param {number} duration - 动画时长
	 * @param {Function} callback - 完成回调
	 */
	animateVolume(audio, fromVolume, toVolume, duration, callback) {
		const startTime = Date.now()
		const volumeDiff = toVolume - fromVolume
		
		const animate = () => {
			const elapsed = Date.now() - startTime
			const progress = Math.min(elapsed / duration, 1)
			
			const currentVolume = fromVolume + (volumeDiff * progress)
			audio.volume = Math.max(0, Math.min(1, currentVolume))
			
			if (progress < 1) {
				requestAnimationFrame(animate)
			} else if (callback) {
				callback()
			}
		}
		
		animate()
	}
	
	/**
	 * 设置主音量
	 * @param {number} volume - 音量值 (0-1)
	 */
	setMasterVolume(volume) {
		this.masterVolume = Math.max(0, Math.min(1, volume))
		this.updateAllVolumes()
		this.saveSettings()
	}
	
	/**
	 * 设置分类音量
	 * @param {string} category - 分类名称
	 * @param {number} volume - 音量值 (0-1)
	 */
	setCategoryVolume(category, volume) {
		this.categoryVolumes[category] = Math.max(0, Math.min(1, volume))
		this.updateAllVolumes()
		this.saveSettings()
	}
	
	/**
	 * 更新所有音频音量
	 */
	updateAllVolumes() {
		for (const [type, audio] of this.preloadedAudio.entries()) {
			const config = AUDIO_CONFIG[type]
			if (config && audio) {
				audio.volume = config.volume * this.getCategoryVolume(type) * this.masterVolume
			}
		}
	}
	
	/**
	 * 获取分类音量
	 * @param {string} type - 音效类型
	 * @returns {number} 分类音量
	 */
	getCategoryVolume(type) {
		if ([AUDIO_TYPES.CLICK, AUDIO_TYPES.SUCCESS, AUDIO_TYPES.ERROR, AUDIO_TYPES.WARNING, AUDIO_TYPES.NOTIFICATION].includes(type)) {
			return this.categoryVolumes.ui
		} else if ([AUDIO_TYPES.GAME_START, AUDIO_TYPES.GAME_END, AUDIO_TYPES.LEVEL_UP, AUDIO_TYPES.CORRECT, AUDIO_TYPES.INCORRECT, AUDIO_TYPES.TIME_WARNING, AUDIO_TYPES.COUNTDOWN].includes(type)) {
			return this.categoryVolumes.game
		} else if ([AUDIO_TYPES.ACHIEVEMENT, AUDIO_TYPES.PERSONAL_BEST, AUDIO_TYPES.STREAK].includes(type)) {
			return this.categoryVolumes.achievement
		} else if ([AUDIO_TYPES.BACKGROUND, AUDIO_TYPES.AMBIENT].includes(type)) {
			return this.categoryVolumes.background
		}
		return 1.0
	}
	
	/**
	 * 启用/禁用音效
	 * @param {boolean} enabled - 是否启用
	 */
	setEnabled(enabled) {
		this.isEnabled = enabled
		if (!enabled) {
			this.stopAll()
		}
		this.saveSettings()
	}
	
	/**
	 * 停止所有音效
	 */
	stopAll() {
		for (const [type] of this.preloadedAudio.entries()) {
			this.stop(type)
		}
		this.audioInstances.clear()
	}
	
	/**
	 * 获取音效状态
	 * @returns {Object} 音效状态
	 */
	getStatus() {
		return {
			isEnabled: this.isEnabled,
			masterVolume: this.masterVolume,
			categoryVolumes: { ...this.categoryVolumes },
			currentBackgroundAudio: this.currentBackgroundAudio,
			activeInstances: this.audioInstances.size,
			preloadedCount: this.preloadedAudio.size
		}
	}
	
	/**
	 * 生成实例ID
	 * @returns {string} 实例ID
	 */
	generateInstanceId() {
		return Date.now().toString(36) + Math.random().toString(36).substr(2)
	}
	
	/**
	 * 保存设置
	 */
	saveSettings() {
		try {
			if (typeof uni !== 'undefined') {
				const settings = {
					isEnabled: this.isEnabled,
					masterVolume: this.masterVolume,
					categoryVolumes: this.categoryVolumes
				}
				uni.setStorageSync('audioSettings', settings)
			}
		} catch (error) {
			console.error('保存音频设置失败:', error)
		}
	}
	
	/**
	 * 重置设置
	 */
	resetSettings() {
		this.isEnabled = true
		this.masterVolume = 1.0
		this.categoryVolumes = {
			ui: 1.0,
			game: 1.0,
			achievement: 1.0,
			background: 1.0
		}
		this.updateAllVolumes()
		this.saveSettings()
	}
	
	/**
	 * 销毁音频管理器
	 */
	destroy() {
		this.stopAll()
		
		// 清理音频实例
		for (const audio of this.preloadedAudio.values()) {
			if (audio && audio.destroy) {
				audio.destroy()
			}
		}
		
		this.preloadedAudio.clear()
		this.audioInstances.clear()
		
		// 清理淡入淡出定时器
		for (const timer of this.fadeTimers.values()) {
			clearTimeout(timer)
		}
		this.fadeTimers.clear()
		
		// 关闭音频上下文
		if (this.audioContext && this.audioContext.close) {
			this.audioContext.close()
		}
	}
}

// 创建全局实例
const audioManager = new AudioManager()

// 便捷方法
export const playAudio = (type, options) => {
	return audioManager.play(type, options)
}

export const stopAudio = (type) => {
	audioManager.stop(type)
}

export const playBackgroundMusic = (type, options) => {
	audioManager.playBackground(type, options)
}

export const stopBackgroundMusic = () => {
	audioManager.stopBackground()
}

export const fadeInAudio = (type, duration, options) => {
	audioManager.fadeIn(type, duration, options)
}

export const fadeOutAudio = (type, duration) => {
	audioManager.fadeOut(type, duration)
}

export const setMasterVolume = (volume) => {
	audioManager.setMasterVolume(volume)
}

export const setCategoryVolume = (category, volume) => {
	audioManager.setCategoryVolume(category, volume)
}

export const setAudioEnabled = (enabled) => {
	audioManager.setEnabled(enabled)
}

export const getAudioStatus = () => {
	return audioManager.getStatus()
}

export const stopAllAudio = () => {
	audioManager.stopAll()
}

export const resetAudioSettings = () => {
	audioManager.resetSettings()
}

// 导出音效类型常量
export { AUDIO_CONFIG }

// 导出管理器实例
export default audioManager